package MyHashMap;

public class MyHashMap<K,V> implements MyMap<K,V> {
    private static final int DEFAULT_INITIAL_CAPACITY = 1<<4;
    private static final float DEFAULT_LOAD_FACTOR = 0.75f;
    private int defaultInitSize;
    private float defaultLoadFactor;

    private int entryUserSize;

    private Entry<K,V>[] talbe = null;

    public MyHashMap(){
        this(DEFAULT_INITIAL_CAPACITY,DEFAULT_LOAD_FACTOR);
    }

    public MyHashMap(int defaultInitialCapacity, float defaultLoadFactor) {
        if(defaultInitialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: "+
                    defaultInitialCapacity);
        if(defaultLoadFactor <= 0 || Float.isNaN(defaultLoadFactor))
            throw new IllegalArgumentException("Illegal load factor: "+
                    defaultLoadFactor);
        this.defaultInitSize = defaultInitialCapacity;
        this.defaultLoadFactor = defaultLoadFactor;

        talbe = new Entry[this.defaultInitSize];
    }

    @Override
    public V put(K k, V v) {
        V oldValue = null;
        if(entryUserSize >= defaultInitSize*defaultLoadFactor){
            resize(2 * defaultInitSize);
        }
        int index = hash(k) & (defaultInitSize - 1);
        if (talbe[index] == null){
            talbe[index] = new Entry<K,V>(k,v,null);
            ++entryUserSize;
        }else {
            Entry<K,V> entry = talbe[index];
            Entry<K,V> e = entry;
            while (e != null){
                if(k == e.getKey() || k.equals(e.getKey())){
                    oldValue = e.value;
                    e.value = v;
                    return oldValue;
                }
                e = e.next;
            }
            talbe[index] = new Entry<K, V>(k,v,entry);
            ++entryUserSize;
        }
        return oldValue;
    }

    private void resize(int i) {
        
    }
    private int hash(K k){
        int hashCode = k.hashCode();
        hashCode = (hashCode >>> 20) ^ (hashCode >>> 12);
        return hashCode ^ (hashCode >>> 7) ^ (hashCode >>> 4);
    }

    @Override
    public V get(K k) {
        return null;
    }

    class Entry<K,V> implements MyMap.Entry<K,V>{
        private K key;
        private V value;
        private Entry<K,V> next;

        public Entry(K key,V value,Entry<K,V> next){
            this.key = key;
            this.value = value;
            this.next = next;
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }
    }
}
